package tests;

public class MyVector<T> implements SimpleCollection<T> {
	
	public static void main(String[] args) {
		MyVector<String> v1 = new MyVector<String>();
		v1.push_front(new String("Hund"));
		v1.print();
	}

	private T[] mObjects; // das Feld (Array) der Objekte
	private final int mIncWidth; // die Weite, um die erweitert werden soll
	private int mNextFree; // Index des nächsten freien Eintrags
	private int mPrevFree; // Index des nächsten freien Eintrags

	@SuppressWarnings("unchecked")
	public MyVector(int initialCapacity, int capacityIncrement) {
		mIncWidth = capacityIncrement;
		mNextFree = 0;
		mPrevFree = 0;
		mObjects = (T[]) new Object[initialCapacity];
	}

	public MyVector(int initialCapacity) {
		this(initialCapacity, 0);
	}

	public MyVector() {
		this(1, 0);
	}

	public void add(T obj) {
		if (mNextFree >= mObjects.length) {
			resizeNext();
		}
		mObjects[mNextFree++] = obj;
	}

	public void resizeNext() {
		final int newSize = mIncWidth == 0 ? mObjects.length * 2
				: mObjects.length + mIncWidth;

		T[] newObjects = (T[]) new Object[newSize];

		for (int i = 0; i < mObjects.length; ++i) {
			newObjects[i] = mObjects[i];
		}

		mObjects = newObjects;
	}

	public void resizePrev() {
		final int newSize = mIncWidth == 0 ? mObjects.length * 2
				: mObjects.length + mIncWidth;

		T[] newObjects = (T[]) new Object[newSize];

		for (int i = 0; i < mObjects.length; ++i) {
			newObjects[i + newSize - mObjects.length] = mObjects[i];
		}

		mNextFree += newSize - mObjects.length;
		mPrevFree = newSize - mObjects.length - 1;
		mObjects = newObjects;

	}

	@Override
	public int size() {
		return mNextFree;
	}

	@Override
	public void push_back(T arg) {
		if (mNextFree == 0 && mPrevFree == 0) {
			--mPrevFree;
		}
		if (mNextFree < 0)
			resizePrev();
		mObjects[mPrevFree--] = arg;
	}

	@Override
	public void push_front(T arg) {
		if (mNextFree == 0 && mPrevFree == 0) {
			++mNextFree;
		}
		if (mPrevFree >= mObjects.length)
			resizeNext();
		mObjects[mNextFree++] = arg;
	}

	@Override
	public T get(int i) throws OutOfBoundsException {
		if (i < size() && i >= 0)
			return mObjects[i];
		else
			throw new OutOfBoundsException();
	}

	@Override
	public void set(int i, T arg) throws OutOfBoundsException {
		if (i < size() && i >= 0)
			mObjects[i] = arg;
		else
			throw new OutOfBoundsException();

	}

	@Override
	public void delete(int i) throws OutOfBoundsException {
		if (i < size() && i >= 0) {
			while (i < mObjects.length - 1) {
				mObjects[i] = mObjects[++i];
			}
			mObjects[--mNextFree] = null;
		} else
			throw new OutOfBoundsException();
	}
	
	void print(){
		for(int i=0;i<mObjects.length;++i){
			System.out.println(mObjects[i]+" ");
		}
	}

}

class OutOfBoundsException extends Exception {
}

interface SimpleCollection<T> {
	int size(); // liefert die Anzahl der Elemente zurück

	void push_back(T arg); // fügt ein neues Element am Ende ein

	void push_front(T arg); // fügt ein neues Element am Anfang

	T get(int i) throws OutOfBoundsException; // liefert das i-te Element

	void set(int i, T arg) throws OutOfBoundsException; // setzt das i-te
														// Element auf arg

	void delete(int i) throws OutOfBoundsException; // löscht das i-te Element
}
